package com.cangshi.shiro.ssesion;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by Eoly on 2017/6/14.
 */
public class OnlineSessionManager {

    public OnlineSessionManager() {

    }

    private EhCacheManager ehCacheManager;

    private SessionManager sessionManager;

    private Set<Serializable> sessionOnlineIds = new HashSet<Serializable>();

    public void addOnlineSession(Serializable sessionId) {
        sessionOnlineIds.add(sessionId);
        updateCache();
    }

    public void letoutSession(Serializable sessionId) {
        Session session = sessionManager.getSession(new DefaultSessionKey(sessionId));
        if (session == null) {
            return;
        }
        session.setAttribute("kickout", true);
    }

    public void removeSessionOnline(Serializable sessionId) {
        if (!sessionOnlineIds.contains(sessionId)) {
            return;
        }
        sessionOnlineIds.remove(sessionId);
        updateCache();
    }

    public Session getSession(Serializable sessionId) {
        sessionOnlineIds = (Set<Serializable>) ehCacheManager.getCache("test").get("online");
        if (sessionOnlineIds == null) {
            sessionOnlineIds = new HashSet<Serializable>();
        }
        try {
            return sessionManager.getSession(new DefaultSessionKey(sessionId));
        } catch (UnknownSessionException e) {
            if (this.sessionOnlineIds.contains(sessionId)) {
                removeSessionOnline(sessionId);
            }
            return null;
        }

    }

    public Map<Serializable, Session> getSessionsOnline() {
        Map<Serializable, Session> sessionsOnlineList = new HashMap<Serializable, Session>();
        for (Serializable sessionId : sessionOnlineIds) {
            Session session = getSession(sessionId);
            if (session == null) {
                continue;
            }
            if (session.getAttribute("kickout") != null) {
                continue;
            }
            sessionsOnlineList.put(sessionId, session);
        }
        return sessionsOnlineList;
    }

    public SessionManager getSessionManager() {
        return sessionManager;
    }

    public void setSessionManager(SessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    public EhCacheManager getEhCacheManager() {
        return ehCacheManager;
    }

    public void setEhCacheManager(EhCacheManager ehCacheManager) {
        this.ehCacheManager = ehCacheManager;
    }

    private void updateCache() {
        ehCacheManager.getCache("test").put("online", sessionOnlineIds);
    }
}
